using Nop.Core.Data;
using Nop.Core.Domain.Messages;
using Nop.Plugin.ActiveForever.ActiveChat.Data;
using Nop.Plugin.ActiveForever.ActiveChat.Models;
using Nop.Services.Configuration;
using Nop.Services.Messages;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml;

namespace Nop.Plugin.ActiveForever.ActiveChat.Services
{
	public class ActiveChatService : IActiveChatService
	{
		private readonly IRepository<BannedClient> _bannedClientRepository;

		private readonly IRepository<ClientChatLog> _clientChatLogRepository;

		private readonly IRepository<CannedResponse> _cannedResponseRepository;

		private readonly ActiveChatSettings _activeChatSettings;

		private readonly IEmailAccountService _emailAccountService;

		private readonly IQueuedEmailService _queuedEmailService;

		private readonly ISettingService _settingService;

		public ActiveChatService(IRepository<ClientChatLog> clientChatLogRepository, IRepository<BannedClient> bannedClientRepository, IRepository<CannedResponse> cannedResponseRepository, ActiveChatSettings activeChatSettings, IEmailAccountService emailAccountService, IQueuedEmailService queuedEmailService, ISettingService settingService)
		{
			_clientChatLogRepository = clientChatLogRepository;
			_bannedClientRepository = bannedClientRepository;
			_cannedResponseRepository = cannedResponseRepository;
			_activeChatSettings = activeChatSettings;
			_emailAccountService = emailAccountService;
			_queuedEmailService = queuedEmailService;
			_settingService = settingService;
		}

		public virtual void GenerateExportFile()
		{
			DateTime now = DateTime.Now;
			string str = string.Concat("ActiveChatDataExport-", now.ToString("MM.dd.yyyy"), ".xml");
			string str1 = Path.Combine(HttpRuntime.AppDomainAppPath, "content\\files\\exportimport", str);
			using (FileStream fileStream = new FileStream(str1, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
			{
				XmlWriterSettings xmlWriterSetting = new XmlWriterSettings
				{
					Encoding = Encoding.UTF8
				};
				using (XmlWriter xmlWriter = XmlWriter.Create(fileStream, xmlWriterSetting))
				{
					xmlWriter.WriteStartDocument();
					xmlWriter.WriteStartElement("ActiveChatDataExport");
					xmlWriter.WriteStartElement("ClientChatLogs");
					foreach (ClientChatLog list in GetAllClientChatLogs().ToList())
					{
						xmlWriter.WriteStartElement("ClientChatLog");
						xmlWriter.WriteElementString("Name", list.Name);
						xmlWriter.WriteElementString("Browser", list.Browser);
						xmlWriter.WriteElementString("ClientIp", list.ClientIp);
						xmlWriter.WriteElementString("ConnectedAt", list.ConnectedAt);
						xmlWriter.WriteElementString("Email", list.Email);
						xmlWriter.WriteElementString("OperatingSystem", list.OperatingSystem);
						xmlWriter.WriteElementString("SessionId", list.SessionId.ToString());
						xmlWriter.WriteElementString("Url", list.Url);
						xmlWriter.WriteStartElement("Transcript");
						xmlWriter.WriteCData(list.Transcript);
						xmlWriter.WriteEndElement();
						xmlWriter.WriteEndElement();
					}
					xmlWriter.WriteEndElement();
					xmlWriter.WriteStartElement("CannedResponses");
					foreach (CannedResponse cannedResponse in GetAllCannedReponses().ToList())
					{
						xmlWriter.WriteStartElement("CannedResponse");
						xmlWriter.WriteElementString("Message", cannedResponse.Message);
						xmlWriter.WriteEndElement();
					}
					xmlWriter.WriteEndElement();
					xmlWriter.WriteStartElement("BannedClients");
					foreach (BannedClient bannedClient in GetAllBannedClients().ToList())
					{
						xmlWriter.WriteStartElement("BannedClient");
						xmlWriter.WriteElementString("BannedOn", bannedClient.BannedOn);
						xmlWriter.WriteElementString("ClientIp", bannedClient.ClientIp);
						xmlWriter.WriteElementString("Name", bannedClient.Name);
						xmlWriter.WriteEndElement();
					}
					xmlWriter.WriteEndElement();
					xmlWriter.WriteEndElement();
					xmlWriter.WriteEndDocument();
					_activeChatSettings.StaticFileName = Path.GetFileName(str1);
					_settingService.SaveSetting(_activeChatSettings);
				}
			}
		}

		public virtual IList<BannedClient> GetAllBannedClients()
		{
		    return _bannedClientRepository.Table.OrderBy(item => item.Id).ToList();
		}

		public virtual IList<CannedResponse> GetAllCannedReponses()
		{
		    return _cannedResponseRepository.Table.OrderBy(item => item.Id).ToList();
		}

		public virtual IList<ClientChatLog> GetAllClientChatLogs()
		{
		    return _clientChatLogRepository.Table.OrderBy(item => item.Id).ToList();
		}

		public virtual ClientChatLog GetClientChatLog(int clientChatLogId)
		{
		    return _clientChatLogRepository.Table.FirstOrDefault(item => item.Id == clientChatLogId);
        }

		public virtual IList<ClientChatLog> GetRecentClientChatLogs()
		{
		    return _clientChatLogRepository.Table.OrderByDescending(item => item.Id).Take(10).ToList();
		}

		public virtual string Import(string fileName)
		{
			string str;
			if (string.IsNullOrEmpty(fileName))
			{
				return "Import failed. Data file not found.";
			}
			try
			{
				string str1 = Path.Combine(HttpRuntime.AppDomainAppPath, "content\\files\\exportimport", fileName);
				XmlDocument xmlDocument = new XmlDocument();
				xmlDocument.Load(str1);
				foreach (ClientChatLog allClientChatLog in GetAllClientChatLogs())
				{
					_clientChatLogRepository.Delete(allClientChatLog);
				}
				foreach (XmlNode elementsByTagName in xmlDocument.GetElementsByTagName("ClientChatLog"))
				{
					ClientChatLog clientChatLog = new ClientChatLog
					{
						Name = elementsByTagName.ChildNodes[0].InnerText,
						Browser = elementsByTagName.ChildNodes[1].InnerText,
						ClientIp = elementsByTagName.ChildNodes[2].InnerText,
						ConnectedAt = elementsByTagName.ChildNodes[3].InnerText,
						Email = elementsByTagName.ChildNodes[4].InnerText,
						OperatingSystem = elementsByTagName.ChildNodes[5].InnerText,
						SessionId = Guid.Parse(elementsByTagName.ChildNodes[6].InnerText),
						Url = elementsByTagName.ChildNodes[7].InnerText,
						Transcript = elementsByTagName.ChildNodes[8].InnerText
					};
					_clientChatLogRepository.Insert(clientChatLog);
				}
				foreach (CannedResponse allCannedReponse in GetAllCannedReponses())
				{
					_cannedResponseRepository.Delete(allCannedReponse);
				}
				foreach (XmlNode xmlNodes in xmlDocument.GetElementsByTagName("CannedResponse"))
				{
					CannedResponse cannedResponse = new CannedResponse
					{
						Message = xmlNodes.ChildNodes[0].InnerText
					};
					_cannedResponseRepository.Insert(cannedResponse);
				}
				foreach (BannedClient allBannedClient in GetAllBannedClients())
				{
					_bannedClientRepository.Delete(allBannedClient);
				}
				foreach (XmlNode elementsByTagName1 in xmlDocument.GetElementsByTagName("BannedClient"))
				{
					BannedClient bannedClient = new BannedClient
					{
						BannedOn = elementsByTagName1.ChildNodes[0].InnerText,
						ClientIp = elementsByTagName1.ChildNodes[1].InnerText,
						Name = elementsByTagName1.ChildNodes[2].InnerText
					};
					_bannedClientRepository.Insert(bannedClient);
				}
				str = "Import completed.";
			}
			catch (Exception exception)
			{
				str = string.Concat("Import failed: ", exception.Message);
			}
			return str;
		}

		public virtual void InsertBannedClient(BannedClient bannedClient)
		{
			if (bannedClient == null)
			{
				throw new ArgumentNullException("bannedClient");
			}
			_bannedClientRepository.Insert(bannedClient);
		}

		public virtual void InsertCannedResponse(CannedResponse cannedResponse)
		{
			if (cannedResponse == null)
			{
				throw new ArgumentNullException("cannedResponse");
			}
			_cannedResponseRepository.Insert(cannedResponse);
		}

		public virtual void InsertClientChatLog(ClientChatLog clientChatLog)
		{
			if (clientChatLog == null)
			{
				throw new ArgumentNullException("clientChatLog");
			}
			_clientChatLogRepository.Insert(clientChatLog);
		}

		public virtual void RemoveBannedClient(int bannedClientId)
		{
		    BannedClient bannedClient = _bannedClientRepository.Table.FirstOrDefault(item => item.Id == bannedClientId);
            if (bannedClient != null)
            {
                _bannedClientRepository.Delete(bannedClient);
            }
		}

		public virtual void SendPostChatEmail(string transcriptXml, string clientName, string operatorName, string clientEmail)
		{
			if (_activeChatSettings.EnablePostChatEmail)
			{
				EmailAccount emailAccountById = _emailAccountService.GetEmailAccountById(_activeChatSettings.OfflineEmailAccountId);
				List<TranscriptMessage> transcriptMessages = new List<TranscriptMessage>();
				if (!string.IsNullOrEmpty(transcriptXml))
				{
					XmlDocument xmlDocument = new XmlDocument();
					xmlDocument.LoadXml(transcriptXml);
					foreach (XmlNode elementsByTagName in xmlDocument.GetElementsByTagName("Message"))
					{
						TranscriptMessage transcriptMessage = new TranscriptMessage
						{
							Message = elementsByTagName.Attributes["Message"].InnerText,
							Recipient = elementsByTagName.Attributes["Recipient"].InnerText,
							Sender = elementsByTagName.Attributes["Sender"].InnerText
						};
						DateTime dateTime = Convert.ToDateTime(elementsByTagName.Attributes["TimeStamp"].InnerText);
						transcriptMessage.TimeStampJS = dateTime.ToString("MMM dd, HH:mm:ss");
						transcriptMessages.Add(transcriptMessage);
					}
				}
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("<table style=\"width: 100%\">");
				foreach (TranscriptMessage transcriptMessage1 in transcriptMessages)
				{
					stringBuilder.Append("<tr>");
					stringBuilder.Append(string.Concat("<td>", transcriptMessage1.TimeStampJS, "</td>"));
					stringBuilder.Append(string.Concat("<td>", transcriptMessage1.Sender, "</td>"));
					stringBuilder.Append(string.Concat("<td>", transcriptMessage1.Recipient, "</td>"));
					stringBuilder.Append(string.Concat("<td>", transcriptMessage1.Message, "</td>"));
					stringBuilder.Append("</tr>");
				}
				stringBuilder.Append("</table>");
				string postChatEmail = _activeChatSettings.PostChatEmail;
				postChatEmail = postChatEmail.Replace("%TRANSCRIPT%", stringBuilder.ToString());
				postChatEmail = postChatEmail.Replace("%VISITORNAME%", clientName);
				postChatEmail = postChatEmail.Replace("%OPERATORNAME%", operatorName);
				QueuedEmail queuedEmail = new QueuedEmail
				{
				    Priority = 5,
				    From = emailAccountById.Email,
				    FromName = emailAccountById.DisplayName,
				    To = clientEmail,
				    ToName = clientName,
				    Bcc = string.Empty,
				    CC = string.Empty,
				    Subject = _activeChatSettings.PostChatEmailSubject,
				    Body = postChatEmail,
				    CreatedOnUtc = DateTime.UtcNow,
				    EmailAccountId = emailAccountById.Id
				};
			    _queuedEmailService.InsertQueuedEmail(queuedEmail);
			}
		}
	}
}